<?php
declare (strict_types = 1);
namespace app\model\tablenot\tool;

use app\model\MyException;
use think\facade\Filesystem;

class Tool
{
    /**
     * 拥有全部数据，模拟tp6框架假分页
     * @param $data
     * @param $page
     * @param $pagesize
     * @return array
     */
    public static function FalsePagination($data,$page,$pagesize)
    {
        $dataSlice = array_slice($data, ($page-1)*$pagesize, $pagesize);
        $total = count($data);
        return array(
            "total" => $total,
            "per_page" => $pagesize,
            "current_page" => $page,
            "last_page" => $total == 0 ? 0 : ceil($total/$pagesize),
            "data" => $dataSlice
        );
    }

    public static function formatBirthday($val){
        if(empty($val)){
            return "";
        }
        try{
            return date("Y-m-d",strtotime($val));
        }catch (\Exception $e){
            return  "";
        }
    }

    public static function getSex($str=""){
        if(is_numeric($str) && $str<10){
            return $str;
        }
        if($str == '男'){
            return  0;
        }
        if($str == "女"){
            return 1;
        }
        return 2;
    }


    /**
     * 获取数组中某个字段的值，支持 xxx.a
     * @param $arr
     * @param $columnArr
     * @return mixed
     */
    public function getMultiArr($arr,$columnArr)
    {
        foreach ($columnArr as $val){
            if(isset($arr[$val])){
                if( is_array($arr[$val])){
                    return $this->getMultiArr($arr[$val],$columnArr);
                }else{
                    return $arr[$val];
                }
            }
        }
    }

    /**
     * 二维数组转换成一维数组
     * @param $TwoArr
     * @return array
     */
    public static function arrTwoToOne($TwoArr)
    {
        foreach ($TwoArr as $key => $val){
            if(is_array($val)){
                unset($TwoArr[$key]); // 为了兼容之前的版本不删除
                if(!empty($val)){
                    foreach ($val as $k => $v){
                        $TwoArr[$key."__".$k] = $v;
                    }
                }
            }
        }
        return $TwoArr;
    }

    public static function getRealIp(){
        if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
            $pos = array_search('unknown', $arr);
            if (false !== $pos) unset($arr[$pos]);
            return trim($arr[0]);
        } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
            return $_SERVER['HTTP_CLIENT_IP'];
        } elseif (isset($_SERVER['REMOTE_ADDR'])) {
            return  $_SERVER['REMOTE_ADDR'];
        }
        return  request()->ip();
    }

    /**
     * 获取13位时间戳
     * @return float
     */
    public static function getMillisecond() {
        list($microsecond , $time) = explode(' ', microtime()); //' '中间是一个空格
        return (float)sprintf('%.0f',(floatval($microsecond)+floatval($time))*1000);
    }

    /**
     * 根据正则过滤号码
     * @param $rule
     * @param $str
     */
    public static function filterRule($rule,$str){
        //手机号 /^1(3|4|5|6|7|8|9)\d{9}$/
        //座机 /0\d{10}$/
        //纯数字 /^[+-]?\d*(\.\d*)?(e[+-]?\d+)?$/
        if (empty($rule)){
            $rule = 'number';
        }
        switch ($rule){
            case "phone":
                $pattern = "/^1(3|4|5|6|7|8|9)\d{9}$/";
                break;
            case "tel":
                $pattern = "/0\d{10}$/";
                break;
            case "number":
                $pattern = "/^(?!.*-.*-)[\w-]{6,14}$/";
                break;
            default:
                return is_numeric($str);
        }
        return preg_match($pattern,$str);
    }

    /**
     * 获取客户端IP地址
     * @param int $type 返回类型 0 返回IP地址 1 返回IPV4地址数字
     * @param bool $adv 是否进行高级模式获取（有可能被伪装）
     * @return mixed
     */
    public static function getIP()
    {
        //$type = $type ? 1 : 0;
        $type = 0;
        $adv = true;
        static $ip = NULL;
        if ($ip !== NULL) return $ip[$type];
        if ($adv) {
            if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
                $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
                $pos = array_search('unknown', $arr);
                if (false !== $pos) unset($arr[$pos]);
                $ip = trim($arr[0]);
            } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
                $ip = $_SERVER['HTTP_CLIENT_IP'];
            } elseif (isset($_SERVER['REMOTE_ADDR'])) {
                $ip = $_SERVER['REMOTE_ADDR'];
            }
        } elseif (isset($_SERVER['REMOTE_ADDR'])) {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
        // IP地址合法验证
        $long = sprintf("%u", ip2long($ip));
        $ip   = $long ? array($ip, $long) : array('0.0.0.0', 0);
        Ip::instance()->getAddress($ip[$type]);
        return $ip[$type];
    }

    /**
     * 通用文件上传
     * @param $fileObj
     * @param $path
     * @return bool|string
     * @throws MyException
     */
    public static function fileUpload($fileObj, $path)
    {
        try {
            if(!isset($fileObj['file']) || empty($fileObj['file'])){
                throw new MyException('上传文件不存在');
            }
            $file_name = $fileObj['file'];
            // 上传文件到服务器
            return Filesystem::disk('public')->putFile($path, $file_name, 'data');
        }catch (MyException $e) {
            echo $e->toJson();
        }
    }

    /**
     * 自动创建文件夹
     * @param $path
     */
    public static function createDir($path)
    {
        if(!file_exists($path)){
            //检查是否有该文件夹，如果没有就创建，并给予最高权限
            mkdir($path, 0777);
        }
        return ;
    }


    public static function toCsv($saveName, $excelCheck,$limit=false){
//        $config   = ['path' => PUBLICE_PATH.'/storage/'];
//        $excel    = new \Vtiful\Kernel\Excel($config);
//        $data = $excel->openFile($saveName)
//            ->openSheet()
//            ->setSkipRows(1)
//            ->getSheetData();
//        $filePath = $excel->fileName('tutorial.xlsx', 'TestSheet1')
//            ->setSkipRows(1)
//            ->output();
//
//// 写入方式打开，将文件指针指向文件末尾。
//        $fp = fopen('./tests/file.csv', 'a');
//
//        $csvResult = $excel->openFile('tutorial.xlsx')
//            ->openSheet()
//            ->putCSV($fp);
    }

    public static function readTxt($saveName,$limit=false){
        $filePath = PUBLICE_PATH.'/storage/'.$saveName;
        $arr = [];
        $rs = file_get_contents($filePath);

        $list = explode("\n",$rs);
        foreach ($list as $v){

            $v = str_replace(',','|',$v);
            $split = explode('|',trim($v));

            if(empty($split[0])){
                continue;
            }
            $tmp[0] = $split[1]??''; //姓名
            $tmp[1] = $split[0]??''; //手机号
            $tmp[2] = $split[2]??''; //备注
            $arr[] = $tmp;
        }

        if($limit && count($arr)>$limit){
            throw new MyException("最多支持{$limit}条记录");
        }
        return $arr;
    }

    public static function readNew($saveName, $excelCheck,$limit=false){
        // 读取测试文件
        // 获取文件名

        ini_set('memory_limit', '1024M');
        $config   = ['path' => PUBLICE_PATH.'/storage/'];
        $excel    = new \Vtiful\Kernel\Excel($config);
        $excel->openFile($saveName,)
            ->openSheet('Sheet1',\Vtiful\Kernel\Excel::SKIP_EMPTY_ROW)
            ->setType([
                \Vtiful\Kernel\Excel::TYPE_STRING,
                \Vtiful\Kernel\Excel::TYPE_STRING,
                \Vtiful\Kernel\Excel::TYPE_STRING,
                \Vtiful\Kernel\Excel::TYPE_STRING,
                \Vtiful\Kernel\Excel::TYPE_STRING,
                \Vtiful\Kernel\Excel::TYPE_STRING,
                \Vtiful\Kernel\Excel::TYPE_STRING,
                \Vtiful\Kernel\Excel::TYPE_STRING,
            ])
        ;


        //看第一行是什么
         $firstRow = $excel->nextRow();
         $tip = $firstRow[0]??'';

         if(strstr($tip,"填写指南")){
             //有填写指南 再跳一行得到表头
             $firstRow = $excel->nextRow();
         }


         $len = 0;
        if(!empty($excelCheck)){
            $len = count($excelCheck);
            // 验证excel格式是不是正确
            foreach ($excelCheck as $key=>$val){
                if(!isset($firstRow[$key])){
                    throw new MyException('字段不存在！请使用系统提供的模板');
                }
                if(strpos($firstRow[$key],$val) === false){
                    throw new MyException('请使用系统提供的模板');
                }
            }
        }

        //setSkipRows()
        $resData = [];
        // 此处判断请使用【!==】运算符进行判断；
// 如果使用【!=】进行判断，出现空行时，返回空数组，将导致读取中断；
        while (($row = $excel->nextRow()) !== NULL) {
            if(!empty($len)){
               $row = array_splice($row,0,$len);
            }
           $resData[] = $row;
        }
//        var_dump($resData);exit;
//
//        $data = $excel->getSheetData();
//        foreach ($data as $k=>$v){
//            if(!self::isEmptyArr($v)){
//                $resData[] = $v;
//            }
//        }

        if(empty($resData)){
            throw new MyException('没有记录可以导入');
        }

        if($limit && count($resData)>$limit){
            throw new MyException("最多支持{$limit}条记录");
        }
        //格式化处理一下
        return $resData;
    }


    public static function isEmptyArr(&$arr){
        $flag = true;
        foreach ($arr as &$v){
            $v = str_replace(array(" ", "\n", "\r"), "", $v);
            if(!empty($v)){
                $flag = false;
            }
        }
        return $flag;
    }

    /**
     * 读取文件内容
     * 可能第一行有tip 要再跳过
     * @param $saveName
     * @param $excelCheck
     * @return array
     * @throws \PhpOffice\PhpSpreadsheet\Exception
     * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception
     */
    public static function readFile($saveName, $excelCheck,$limit=false,$hasTip=false)
    {
//        try {
//            // 获取文件名
//            $filePath = PUBLICE_PATH.'/storage/'.$saveName;
//
//            if(!file_exists($filePath)){
//                //检查是否有该文件夹，如果没有就创建，并给予最高权限
//                mkdir($filePath, 0777);
//            }
//            $inputFileType = IOFactory::identify($filePath); //传入Excel路径
//            $excelReader   = IOFactory::createReader($inputFileType); //Xlsx
//            $PHPExcel      = $excelReader->load($filePath); // 载入excel文件
//            $sheet         = $PHPExcel->getSheet(0); // 读取第一個工作表
//
//            $res_arr = $sheet->toArray();
//
//            $tip = $res_arr[0][0]??'';
//            if(strstr($tip,"填写指南")){
//                unset($res_arr[0]);
//                $res_arr = array_values($res_arr);
//            }
//
////            if($hasTip){
////
////            }
//
//            // 验证excel格式是不是正确
//            foreach ($excelCheck as $key=>$val){
//                if(!isset($res_arr[0][$key])){
//                    throw new MyException('字段不存在！请使用系统提供的模板');
//                }
//                if(strpos($res_arr[0][$key],$val) === false){
//                    throw new MyException('请使用系统提供的模板');
//                }
//            }
//            if($limit){
//                if(count($res_arr)>$limit){
//                    throw new MyException("最多支持{$limit}条记录");
//                }
//            }
//            unset($res_arr[0]);
//
//            // excel读取完后删除
//            //unlink($filePath);
//            // 过滤掉空行
//            foreach ($res_arr as $key=>$val){
//                $del = true;
//                foreach ($val as $v){
//                    if(!empty($v)){
//                        $del = false;
//                    }
//                }
//                if($del){
//                    unset($res_arr[$key]);
//                }
//            }
//            return array_values($res_arr);
//        } catch (MyException $e) {
//            echo $e->toJson();
//        }
    }


    /**
     * 管理员密码加密方式
     * @param $password  密码
     * @return string
     */
    public static function password($password)
    {
        return md5($password);
    }

    /**
     * 获取数组重复数据
     * @param $array
     * @return array
     */
    public static function FetchRepeatMemberInArray($array) {
        // 获取去掉重复数据的数组
        $unique_arr = array_unique ( $array );
        // 获取重复数据的数组
        return array_diff_assoc ( $array, $unique_arr );
    }

    /**
     * 字节转文件大小
     * @param $size 字节大小
     * @return string
     */
    public static function convert($size)
    {
        $unit=array('b','kb','mb','gb','tb','pb');
        return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];
    }

    /**
     * 判断一个一维数组里面的值是否在另外一个一维数组里面 例如 func(['pageNo','pageSize','stime','etime'], $this->get)
     * @param $smallArr array  小数组  Array([0] => maxNum,[1] => exchangeType,[2] => awardNum,[3] => prize)
     * @param $bigArr array    大数组包含所有的小数组  Array([id] => 11,[maxNum] => 100,[exchangeType] => 1,[awardNum] => 50000,[prize] => 500)
     * @return false
     */
    public static function checkParam($smallArr, $bigArr)
    {
        try {
            foreach ($smallArr as $val) {
                if (!isset($bigArr[$val])) {
                    throw new MyException("字段:".$val." 必填");
                }
            }
        } catch (MyException $e) {
            echo $e->toJson();
        }
        return true;
    }

    /**
     * 获取传入的时间是星期几，星期一到星期天 为 1到7
     * @param $day
     * @return false|int|string
     */
    public static function getWeekNum($day)
    {
        return date("w",strtotime($day)) == 0 ? 7 : date("w",strtotime($day));
    }

    /**
     * 重置数组下标，把数组的某个字段设置为下标,自己控制下标必须是唯一的
     * @param $arr
     * @param $column
     * @return array
     */
    public static function initArrSubscript($arr, $column)
    {
        $newArr = array();
        foreach ($arr as $val)
        {
            $newArr[$val[$column]] = $val;
        }
        return $newArr;
    }

    /**
     *求两个已知经纬度之间的距离,单位为米
     *@param lng1,lng2 经度
     *@param lat1,lat2 纬度
     *@return float 距离，单位米
     *@edit www.jbxue.com
     **/
    public static function getDistance($lng1,$lat1,$lng2,$lat2){
        //将角度转为狐度
        $radLat1=deg2rad($lat1);//deg2rad()函数将角度转换为弧度
        $radLat2=deg2rad($lat2);
        $radLng1=deg2rad($lng1);
        $radLng2=deg2rad($lng2);
        $a=$radLat1-$radLat2;
        $b=$radLng1-$radLng2;
        return 2*asin(sqrt(pow(sin($a/2),2)+cos($radLat1)*cos($radLat2)*pow(sin($b/2),2)))*6378.137*1000;
    }

    /**
     *  将文件格式转换成MP3
     * @param $address
     */
    public static function musicToMp3($address)
    {
        $temp = explode("?",$address);
        $arr = explode(".",$temp[0]);
        $countArr = count($arr);
        // 后缀
        $type = $arr[$countArr-1];
        if(strtolower($type) == "mp3"){
            return $address;
        }
        $Absolutepath = dirname(dirname(dirname(__FILE__)))."/public/temp/";
        $fileNameStr = explode("/",$arr[$countArr-2]);
        $fileName = end($fileNameStr).".".$type;
        $transferFileName = end($fileNameStr).".mp3";

        // 先将文件下载到本地服务器
        $selfModel = new self();
        $httpcopy = $selfModel->downFile($address, $Absolutepath, $fileName);

        if($httpcopy){
            // 下载成功了，转换文件格式,为了保证文件存在，不能转换，所以得先删除文件
            if(file_exists($Absolutepath.$transferFileName)){
                unlink($Absolutepath.$transferFileName);
            }
            $shell = "ffmpeg  -i ".$Absolutepath.$fileName."  -codec:a libmp3lame -b:a 128k  ".$Absolutepath.$transferFileName." &&  echo 'success'";
            $shellExec = exec($shell);
            if($shellExec == "success"){
                // 格式转换成功先删除转换前的文件
                unlink($Absolutepath.$fileName);
                return $_SERVER['HTTP_HOST']."/temp/".$transferFileName;
            }
        }
        return $address;
    }


    /**
     * 获取curl的路径的返回数据 get
     * @param $url
     * @param string $data
     * @param bool $jsonDecode
     * @return bool|mixed|string
     */
    public static function getCurl($url,$jsonDecode = true)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_REFERER, $url);
//        curl_setopt($ch, CURLOPT_USERAGENT, 'Eduugo Server Nginx 1.1');
        curl_setopt($ch,CURLOPT_TIMEOUT,10);
        $output = curl_exec($ch);

        curl_close($ch);
        if ($jsonDecode) {
            $output = json_decode($output, true);
        }
        return $output;
    }

    /**
     * 根据手机号获取运营商
     * @param $phone
     * @return string
     */
    public static function getphoneOp($phone)
    {
        $phone = trim($phone);
        $isChinaMobile = "/^170[356]\d{7}$|^1440\d{7}$|^(?:13[4-9]|147|15[0-27-9]|165|178|18[2-478]|19[578])\d{8}$/"; //移动方面最新答复
        $isChinaUnion = "/^170[4789]\d{7}$|(?:13[0-2]|145|15[56]|16[67]|171|17[56]|18[56]|196)\d{8}$/"; //向联通微博确认并未回复
        $isChinaTelcom = "/^170[0-2]\d{7}$|^(?:133|153|162|177|173|18[019]|19[0139])\d{8}$/"; //1349号段 电信方面没给出答复，视作不存在
        $isChinaGd = "/^192\d{8}$/";//广电
        // $isOtherTelphone = "/^170([059])\\d{7}$/";//其他运营商
        if (preg_match($isChinaMobile, $phone)) {
            $com = "中国移动";
        } elseif (preg_match($isChinaUnion, $phone)) {
            $com = "中国联通";
        } elseif (preg_match($isChinaTelcom, $phone)) {
            $com = "中国电信";
        } elseif (preg_match($isChinaGd, $phone)) {
            $com = "中国广电";
        } else {
            $com = "未知";
        }

        return $com;
    }
    /**
     * 获取curl的路径的返回数据 post
     * @param $url
     * @param $postData
     * @param bool $jsonDecode
     * @return bool|mixed|string
     */
    public static function postCurl($url, $postData)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        // post数据
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        // post的变量
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
        curl_setopt($ch, CURLOPT_REFERER, $url);
        curl_setopt($ch, CURLOPT_USERAGENT, 'Server Nginx 1.1');
        curl_setopt($ch,CURLOPT_TIMEOUT,10);

        $output = curl_exec($ch);
        curl_close($ch);

        $output = json_decode($output, true);
        return $output;
    }

    public static function postCurlJson($url,$params){
        $data_string = json_encode($params,true);
        // 请求开始
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $header = array(
            'Content-Type: application/json; charset=utf-8',
        );
        curl_setopt($ch, CURLOPT_HTTPHEADER,$header);
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        // 接口返回结果信息
        $output = curl_exec($ch);
        curl_close($ch);

        $output = json_decode($output, true);
        return $output;
    }

    /**
     * 随机生成
     * @param int $length
     * @param string $base
     * @return string
     */
    public static function getRandom($length=12, $base="1234567890abcdefghijklmnopqrstuvwxyz"){
        $len = strlen($base)-1;
        $str = "";
        for($i=0;$i<$length;$i++){
            $str .= $base[rand(0,$len)];
        }
        return $str;
    }

    /**
     * 随机生成大写字母
     * @param int $length
     * @param string $base
     * @return string
     */
    public static function getRandomBigChar($length=12, $base="ABCDEFGHIJKLMNOPQRSTUVWXYZ"){
        $len = strlen($base)-1;
        $str = "";
        for($i=0;$i<$length;$i++){
            $str .= $base[rand(0,$len)];
        }
        return $str;
    }

    /**
     * 判断一维数组里面的值是不是相同的
     * @param $arrOne
     * @param $arrTwo
     */
    public static function arrIsSame($arrOne, $arrTwo)
    {
        if( !array_diff($arrOne, $arrTwo) && !array_diff($arrTwo, $arrOne)){
            // 即相互都不存在差集，那么这两个数组就是相同的了，多数组也一样的道理
            return true;
        }else{
            return false;
        }
    }

    /**
     * 把二维数据的某个字段，转化成逗号隔开的字符串
     * @param $arr
     * @param $column
     * @return string
     */
    public static function arrToColumnStr($arr, $column){
        return implode(",", array_column($arr,$column));
    }

    /**
     * 远程下载文件
     * @param $url
     * @param $file
     * @return false|int
     */
    public static function fileDownload($url, $file)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_POST, 0);
        curl_setopt($ch,CURLOPT_URL,$url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $file_content = curl_exec($ch);
        curl_close($ch);
        $downloaded_file = fopen($file, 'w');
        fwrite($downloaded_file, $file_content);
        fclose($downloaded_file);
    }

    /**
     * 获取linux服务器信息
     * @return array
     */
    public static function getLinuxCpuMem()
    {
        $data = array();
        $fp = popen('top -b -n 2 | grep -E "(Cpu\(s\))|(KiB Mem)"', "r");
        $rs = '';
        while(!feof($fp)){
            $rs .= fread($fp, 1024);
        }
        pclose($fp);
        $sys_info = explode("\n", $rs);
        $cpu_info = explode(",", $sys_info[2]);
        $data['cpu'] = trim(trim($cpu_info[0], '%Cpu(s): '), 'us'); //百分比

        $mem_info = explode(",", $sys_info[3]); //内存占有量 数组
        $mem_total = trim(trim($mem_info[0], 'KiB Mem : '), ' total');
        $mem_used = trim(trim($mem_info[2], 'used'));
        $data['mem'] = round(100 * intval($mem_used) /     intval($mem_total), 2); //百分比

        // 获取硬盘
        $fp = popen('df -lh | grep -E "^(/)"', "r");
        $rs = fread($fp, 1024);
        pclose($fp);
        $rs = preg_replace('/\s{2,}/', ' ', $rs);  //把多个空格换成 “_”
        $hd = explode(" ", $rs);
        $data['disk']['remain'] = trim($hd[3], 'G'); //磁盘可用空间大小 单位G
        $data['disk']['per'] = trim($hd[4], '%'); //挂载点 百分比
        return $data;
    }

    /**
     * 关联查询model中的 关联表为null转换成array
     * @param $obj
     * @param $columnArr
     * @return mixed
     */
    public static function modelNullToArr(&$obj,$columnArr)
    {
        foreach ($columnArr as $column){
            foreach ($obj['data'] as $key=>$val){
                if($val[$column] == null){
                    $obj['data'][$key][$column] = array();
                }
            }
        }
    }

    /**
     * 获取邀请码
     * @return string
     */
    public static function ActiveCode(){
        $code =self::getRandom(4,'abcdefghijklmnopqrstuvwxyz').self::getRandom(2,'1234567890');
        return $code;
    }

    /**
     * 获取周的日期
     * @return array
     */
    public static function GetWeek(){
        $date = date("Y-m-d");  //当前日期
        $Month_date = date("Y-m-1");  //当月1号日期
        $first=1; //$first =1 表示每周星期一为开始时间 0表示每周日为开始时间

        $w = date("w", strtotime($date));  //获取当前周的第几天 周日是 0 周一 到周六是 1 -6

        $d = $w ? $w - $first : 6;  //如果是周日 -6天
        $time  = time();

        $now_start = date("Y-m-d", strtotime(date('Y-m-d',$time - (($w -1) * 86400)))); //本周开始时间

        $now_end = date("Y-m-d", strtotime("$now_start +6 days"));  //本周结束时间

        $last_start = date('Y-m-d',strtotime("$now_start - 7 days"));  //上周开始时间

        $last_end = date('Y-m-d',strtotime("$now_start - 1 days"));  //上周结束时间

        $lastMonthStart = date('Y-m-1 00:00:00', strtotime("-1 month", strtotime($date)));//上个月开始时间

        $lastMonthEnd = date('Y-m-d H:i:s', strtotime('-1 sec', strtotime($Month_date)));//上个月结束时间

        return ['now_start'=>$now_start,'now_end'=>$now_end,'last_start'=>$last_start,'last_end'=>$last_end,'last_month_start'=>$lastMonthStart,'last_month_end'=>$lastMonthEnd];
    }

    /**
     * 指定日期循环
     * @return array
     */
    public static function DayStartEnd($start_time,$end_time){
        $arr=array();
        $diff= strtotime($end_time)-strtotime($start_time);
        $num = $diff/(24*60*60);
        for ($i=0; $i < $num; $i++) {
            $selectTime = date("Y-m-d",strtotime("$end_time - $i days"));//重点，指定日期加减多少天
            array_push($arr,$selectTime);
         }
        return  array_reverse($arr);
    }

    /**
     * 查找手机号码是不是在指定的号码段里面
     * @param $mobileArr
     * @param $mobile
     * @return bool
     */
    public static function notMobileNum($mobileArr,$mobile)
    {
        foreach ($mobileArr as $val)
        {
            $length =  strlen($val);
            $checkMobile = mb_substr($mobile,0,$length);
            if($val == $checkMobile){
                return true;
            }
        }
        return false;
    }

    /**
     * 获取汉字拼音大写首字母
     * @param [type] $str
     * @return void
     */
    public static function getFirstChar($str)
    {
        $fchar = ord(substr((string) $str, 0, 1));
        if($fchar < 127){
            if (($fchar >= ord("a") and $fchar <= ord("z")) or ($fchar >= ord("A") and $fchar <= ord("Z"))) {
                return strtoupper(chr($fchar));
            }else{
                return "#";
            }
        }else{
            $s = iconv("UTF-8", "GBK", (string) $str);
            $asc = ord($s[0]) * 256 + ord($s[1]) - 65536;
            if ($asc >= -20319 and $asc <= -20284) {
                return "A";
            }

            if ($asc >= -20283 and $asc <= -19776) {
                return "B";
            }

            if ($asc >= -19775 and $asc <= -19219) {
                return "C";
            }

            if ($asc >= -19218 and $asc <= -18711) {
                return "D";
            }

            if ($asc >= -18710 and $asc <= -18527) {
                return "E";
            }

            if ($asc >= -18526 and $asc <= -18240) {
                return "F";
            }

            if ($asc >= -18239 and $asc <= -17923) {
                return "G";
            }

            if ($asc >= -17922 and $asc <= -17418) {
                return "H";
            }

            if ($asc >= -17417 and $asc <= -16475) {
                return "J";
            }

            if ($asc >= -16474 and $asc <= -16213) {
                return "K";
            }

            if ($asc >= -16212 and $asc <= -15641) {
                return "L";
            }

            if ($asc >= -15640 and $asc <= -15166) {
                return "M";
            }

            if ($asc >= -15165 and $asc <= -14923) {
                return "N";
            }

            if ($asc >= -14922 and $asc <= -14915) {
                return "O";
            }

            if ($asc >= -14914 and $asc <= -14631) {
                return "P";
            }

            if ($asc >= -14630 and $asc <= -14150) {
                return "Q";
            }

            if ($asc >= -14149 and $asc <= -14091) {
                return "R";
            }

            if ($asc >= -14090 and $asc <= -13319) {
                return "S";
            }

            if ($asc >= -13318 and $asc <= -12839) {
                return "T";
            }

            if ($asc >= -12838 and $asc <= -12557) {
                return "W";
            }

            if ($asc >= -12556 and $asc <= -11848) {
                return "X";
            }

            if ($asc >= -11847 and $asc <= -11056) {
                return "Y";
            }

            if ($asc >= -11055 and $asc <= -10247) {
                return "Z";
            }
            return '#';
        }
    }

    /**
     * 日期搜索
     * @param $date
     * @return array
     */
    public static function start_end_time($date){
        switch ($date){
            case(1):
                //今天
                $s_created_at=date('Y-m-d 00:00:00',time());
                $e_created_at=date('Y-m-d 23:59:59',time());
                break;
            case(2):
                //昨天
                $s_created_at=date('Y-m-d 00:00:00',strtotime('-1day'));
                $e_created_at=date('Y-m-d 23:59:59',strtotime('-1day'));
                break;
            case(3):
                //本周
                $date_info =Tool::GetWeek();
                $s_created_at =$date_info['now_start'];
                $e_created_at =date('Y-m-d 23:59:59',time());
                break;
            case(4):
                //近一个月
                $s_created_at = date('Y-m-d',strtotime('-30day'));
                $e_created_at = date('Y-m-d 23:59:59',time());
                break;
            case(5):
                //近三个月
                $s_created_at = date('Y-m-d',strtotime('-90day'));
                $e_created_at = date('Y-m-d 23:59:59',time());
                break;
            default:
                $s_created_at=date('Y-m-d 00:00:00',time());
                $e_created_at=date('Y-m-d 23:59:59',time());
                break;
        }
        $arr=array();
        $arr['s_created_at']=$s_created_at;
        $arr['e_created_at']=$e_created_at;
        return  $arr;
    }
    /**
     * 计算一维数组中值出现的次数
     * @param $arr array 数组
     * @param $default int 默认值
     * @return array
     */
    public static function ArrCount($arr,$default=0){
        $newArr = array();
        foreach ($arr as $k => $v) {
            if(!$v){
                $v =$default;
            }
            if(empty($newArr[$v])){
                $newArr[$v] = 1;
            }else{
                $newArr[$v] ++;
            }
        }
        return $newArr;
    }

    /**
     * 用户账户判断
     * @param $str
     */
    public static function UserAccount($str){
        //账号使用规则：使用6-30个字母（区分大小写）、数字，只能使用字母开头
        if (preg_match('/^[a-zA-Z]\w{5,29}$/',$str)){
            return true;
        }else{
            return false;
        }
    }
    /**
     *  数组中选择需要的字段
     * @param $arr
     * @param $column
     * @return mixed
     */
    public static function ArraySelectColumn(&$arr, $column)
    {
        if(empty($arr)){
            return ;
        }
        foreach ($arr as $key=>$val){
            if(!in_array($key,$column)){
                unset($arr[$key]);
            }
        }
    }
    /**
     * 按照指定数量分块
     * @param array $data
     * @param number $num
     * @return array
     */
    public static function split( $data, $num = 5 )
    {
        $arrRet = array();
        if( !isset($data) || empty($data)){
            return $arrRet;
        }
        $iCount = count( $data )/$num;
        if(!is_int($iCount)){
            $iCount = ceil($iCount);
        }else {
            $iCount += 1;
        }
        for($i=0; $i<$iCount;++$i ){
            $arrInfos = array_slice( $data, $i*$num, $num );
            if(empty( $arrInfos )){
                continue;
            }
            $arrRet[] = $arrInfos;
            unset( $arrInfos );
        }
        return $arrRet;
    }

    /**
     * 获取一个日期范围内的日期
     * @param int $interval 日期范围
     * @param string $type 取值类型，-：获取之前日期；+：获取之后的日期
     * @return array
     */
    public static function getDateInterval(int $interval,string $type) :array
    {
        $dateArr = [];
        for ($i = $interval - 1; $i >= 0; $i--) {
            array_push($dateArr, date('Y-m-d', strtotime("{$type}{$i} day")));
        }
        if($type=='+')$dateArr=array_reverse($dateArr);
        return $dateArr;
    }

#################################   万能排序  一维数组和多维数组都适用  开始 #####################################
    /**
     * 最终排序
     * @param $data         需要排序的数组
     * 字段|排序类型|按照什么类型排序number:数字,chinese中文，time时间，string字符串
     * classInfo_sort|asc|number,userInfo_name|asc|chinese
     * @param $sortInfo    排序信息
     *
     */
    public static function arraySort(&$data,$sortInfo){
        if(empty($data)){
            return ;
        }

        $sortInfoArr = explode(",",$sortInfo);
        foreach ($sortInfoArr as $key=>$val){
            $sortInfoArr[$key] = explode("|",$val);
        }
        // 获取所有需要排序的字段,把他放在最外层数组，用来排序
        $sortColumn = array_column($sortInfoArr,0);
        foreach ($data as $key=>$val){
            foreach ($sortColumn as $column){
                $columnArr = explode(".",$column);
                if(count($columnArr) == 2){
                    $columnValue = $val;
                    foreach ($columnArr as $v){
                        $columnValue = isset($columnValue[$v]) ? $columnValue[$v] : "";
                    }
                    $data[$key][$column] = $columnValue;
                }
            }
        }
        // 开始排序
        $selfModel = new self();
        $selfModel->arraySortOpen($data,$sortInfoArr,0);
        $selfModel->arraySortClose($data, count($sortInfoArr));
        // 去除掉用来排序而添加的字段
        $sortColumn = array_column($sortInfoArr,0);
        foreach ($data as $key=>$val){
            foreach ($sortColumn as $column){
                $columnArr = explode(".",$column);
                if(count($columnArr) == 2) {
                    unset($data[$key][$column]);
                }
            }
        }

    }

    //排序数据
    private function arraySortOpen(&$data,$sortInfoArr,$i){
        $this->arraySortCheck($data,$sortInfoArr[$i][0],$sortInfoArr[$i][1],$sortInfoArr[$i][2]);
        foreach ($data as $val){
            $rs[$val[$sortInfoArr[$i][0]]] = isset($rs[$val[$sortInfoArr[$i][0]]]) ? $rs[$val[$sortInfoArr[$i][0]]] : array();
            array_push($rs[$val[$sortInfoArr[$i][0]]], $val);
        }
        $data = $rs;
        $i++;
        if(count($sortInfoArr) > $i){
            foreach ($data as $key=>$val){
                $this->arraySortOpen($data[$key],$sortInfoArr,$i);
            }
        }
    }

    //排序数据后的数据返回正我们需要的原始数据格式
    private function arraySortClose(&$data,$num){
        $rs = array();
        foreach ($data as $key=>$val){
            $val = array_values($val);
            $rs = array_merge($rs,$val);
        }
        $num--;
        $data = $rs;
        if($num>0){
            $this->arraySortClose($data,$num);
        }
    }


    /**
     * 检查用那种排序方法开始排序
     * @param $arr          需要排序的数组
     * @param $column       需要排序的字段
     * @param $sortType     desc或者asc
     * @param $sortFunc     number:数字,chinese中文，time时间，string字符串
     */
    private function arraySortCheck(&$arr,$column,$sortType,$sortFunc){
        switch ($sortFunc) {
            case "number":
                $this->arraySortCommon($arr,$column,$sortType);
                break;
            case "chinese":
                $this->arraySortChinese($arr,$column,$sortType);
                break;
            case "time":
                $this->arraySortTime($arr,$column,$sortType);
                break;
            case "string":
                //
                $this->arraySortCommon($arr,$column,$sortType);
                break;
            default:
                break;
        }
    }

    /**
     * 二维数组排序
     * @param $arr  数组
     * @param $column 按照什么字段排序
     * @param $sortType 排序方式 asc 升序， desc降序
     * @return mixed
     */
    public static function arraySortCommon(&$arr,$column,$sortType){
        $sortName = array_column($arr,$column);
        $sortArr = ['asc'=>SORT_ASC,'desc'=>SORT_DESC];
        array_multisort($sortName,$sortArr[$sortType],$arr);
    }

    /**
     * 按照中文排序
     * @param $arr
     * @param $columns
     * @param $sortType
     */
    public static function arraySortChinese(&$arr,$columns,$sortType)
    {
        $columnArr = explode(",",$columns);
        $sortColumnArr = $arr;
        foreach ($columnArr as $val){
            $sortColumnArr = array_column($sortColumnArr, $val);
        }
        $coll = collator_create('zh-CN'); // 使用中国大陆的语言习惯（拼音排序）
        usort($sortColumnArr, [$coll, 'compare']);
        $rs = array();
        foreach ($sortColumnArr as $sortArr){
            foreach ($arr as $val){
                $nowColumn = $val; //当前对比的字段是
                foreach ($columnArr as $v){
                    $nowColumn = $nowColumn[$v];
                }
                if($sortArr == $nowColumn){
                    $sortType == "asc" ? array_push($rs, $val) : array_unshift($rs, $val);
                }
            }
        }
        $arr = $rs;
    }

    /**
     * 二维数组排序 冒泡
     * @param $arr  数组
     * @param $columns 字段
     * @param $sortType 排序方式 asc 升序， desc降序
     * @return mixed
     * Tool::arraySortMp($xuanxiuList,'xuanxiuTimetableInfo,course_stime','desc');
     */
    public static function arraySortTime(&$arr,$columns,$sortType){
        $count = count($arr);
        $columnArr = explode(",",$columns);
        //外层控制排序轮次
        for($i=0; $i<$count-1; $i++){
            //内层控制每轮比较次数
            for($j=0; $j< $count-1-$i; $j++){
                $qian = '';
                $hou = '';
                foreach ($columnArr as $val){
                    $qian = $qian == '' ? $arr[$j][$val] : $qian[$val];
                    $hou = $hou == '' ? $arr[$j+1][$val] : $hou[$val];
                }
                if($sortType == "desc"){
                    if(strtotime($qian) < strtotime($hou)){
                        $temp        = $arr[$j];
                        $arr[$j]     = $arr[$j+1];
                        $arr[$j+1]   = $temp;
                    }
                }else{
                    if(strtotime($qian) > strtotime($hou)){
                        $temp        = $arr[$j];
                        $arr[$j]     = $arr[$j+1];
                        $arr[$j+1]   = $temp;
                    }
                }

            }
        }
    }
#################################   万能排序  一维数组和多维数组都适用  end #####################################

}